package com.upcoming.common;

import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Map;

import com.upcoming.common.MD5Utils;

/**
 * 作者：tianjiayuan
 * 创建时间：2018-05-10 11:19
 * 类描述：
 * 修改人：
 * 修改时间：
 */
public class AccessToken extends Token {

    private static Logger logger = LoggerFactory.getLogger(AccessToken.class);

    private final static String ISSUER = "SKA_2.0";
    public final static int ACCESSTOKEN_STORE_EXPIRES_SECOND = 60 * 60 * 2;// token有效期 2小时
    public final static long ACCESSTOKEN_STORE_EXPIRES_MILLISECOND = (long) ACCESSTOKEN_STORE_EXPIRES_SECOND * 1000L;// token有效期 2小时

    private String appId;


    private AccessToken() {
        this.setIssueTime(System.currentTimeMillis());
        this.setExpires(System.currentTimeMillis() + ACCESSTOKEN_STORE_EXPIRES_MILLISECOND);
        this.setSignature(getUniqueID());//TODO
        this.setIssuer(ISSUER);
    }

    /**
     * 生成一个Token
     *
     * @param appId
     * @return
     */
    public static AccessToken issue(final String appId) {
        AccessToken accessToken = new AccessToken();
        accessToken.setAppId(appId);
        return accessToken;
    }

    /**
     * 将Token转为base64编码格式
     *
     * @return
     */
    @Override
    public String toBase64Encode() {
        StringBuffer input = new StringBuffer();
        input.append("{");
        input.append("\"expire\"").append(":").append(getExpires()).append(",");
        input.append("\"issueTime\"").append(":").append(getIssueTime()).append(",");
        input.append("\"issuer\"").append(":\"").append(getIssuer()).append("\",");
        input.append("\"signature\"").append(":\"").append(getSignature()).append("\",");
        input.append("\"appId\"").append(":\"").append(getAppId()).append("\"");
        input.append("}");
        return new sun.misc.BASE64Encoder().encode(input.toString().getBytes()).replaceAll("(?:\r\n|\n\r|\n|\r)", "");
    }

    /**
     * 将accessToken的base64字符串转为AccessToken对象
     *
     * @param base64Str
     * @return
     */
    public static AccessToken decodeBase64(String base64Str) {
        JSONObject jsonToken = JSONObject.fromObject(new String(new Base64().decode(base64Str)));
        Map<String, Object> map = (Map<String, Object>) jsonToken;

        AccessToken accessToken = new AccessToken();
        Long expire = (Long) map.get("expire");
        Long issueTime = (Long) map.get("issueTime");
        String issuer = String.valueOf(map.get("issuer"));
        String signature = String.valueOf(map.get("signature"));
        String appId = String.valueOf(map.get("appId"));

        accessToken.setExpires(expire);
        accessToken.setIssuer(issuer);
        accessToken.setIssueTime(issueTime);
        accessToken.setSignature(signature);
        accessToken.setAppId(appId);

        return accessToken;
    }

    /**
     * 对参数进行签名
     *
     * @param secert     签名秘钥
     * @param parameters 要签名的参数
     * @return
     */
    public static String signatureParameters(String secert, Map<String, Object> parameters) {
        if (StringUtils.isEmpty(secert) || parameters == null || parameters.isEmpty()) {
            return null;
        }
        parameters.remove("signature");
        Object[] array = parameters.keySet().toArray();
        Arrays.sort(array);
        StringBuffer values = new StringBuffer();
        for (Object i : array) {
            values.append(parameters.get(i.toString()));
        }
        values.append(secert);

        return MD5Utils.md5(values.toString());
    }

    public String getAppId() {
        return appId;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }
}
